
from flask import json
from typing import List
from calendar import month_name
from concurrent.futures import Executor
# from tool import config_manager
import os
import sys
import time
import logging
import copy
import threading


# 添加项目根目录到Python路径
project_root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
sys.path.insert(0, project_root)
# print(project_root)


from src.backend.anchor_manager import AnchorManager
from src.core.config_manager import ConfigManager,Host
from src.core.ssh_connection import SSHConnectionManager
from src.core.command_executor import CommandExecutor
from src.core.result_collector import TaskResult
from src.core.scp_tool import SCPTool

# from src.backend.data_bridge import DataBridge
logger = logging.getLogger(__name__)

class TaskServer:
    def __init__(self):

        self.anchor_register_file = "./config/anchors/anchor_register.yaml"
        self.login_file = "./config/anchors/login.yaml"
        self.anchor_manager = AnchorManager(self.anchor_register_file)
        self.login_config = ConfigManager(self.login_file)
        self.remote_hosts = self.login_config.hosts
        self.local_shell_init_task = self.login_config.tasks[0]
        self.temp_shell_init_task = self.login_config.tasks[1]
        self.ssh_manager = SSHConnectionManager()
        self.command_executor = CommandExecutor(self.ssh_manager)
        self.scp_tool_map = {}
        self.scp_thread_map = {}
        

    async def login_remote_preset(self):
        await self.command_executor.execute_tasks(self.login_config)


    async def login_remote(self,data:dict) :

        # 1. 解析参数
        name = data.get("name")
        host = data.get("host")
        port = data.get("port")
        username = data.get("username")
        password = data.get("password")
        if not name or not host or not port or not username or not password:
            print("参数错误")
            return False,"参数错误"


        # 2. 检查是否已存在
        key = f"{name}|{host}:{port}|{username}"
        if self.ssh_manager.has_connection(key):
            print("主机已存在")
            health_check = self.ssh_manager.health_check()
            print("健康检查:", health_check)
            return True,"主机已存在"


        host = Host(name=name,host=host,port=port,username=username,password=password)
        
        try:
            # 获取远程连接
            self.ssh_manager.get_connection(host)
            self.login_config.hosts[name] = host
            self.remote_hosts[name] = host

            load_time = time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime())
            cmd_output_dir = "cmd_output_log/"+"frontend-remotelogin-"+"-"+load_time
            await self.command_executor.ssh_manager_stream.execute_streaming_command(
                host=host,
                task=self.local_shell_init_task,
                cmd_output_dir=cmd_output_dir)

            connection_stats = self.ssh_manager.get_connection_stats()
            print("连接信息:", connection_stats)

            health_check = self.ssh_manager.health_check()
            print("健康检查:", health_check)

            return True,"登录成功"
        except Exception as e:
            logger.error(f"登录失败: {key}, 错误: {e}")
            return False,str(e)


    async def add_command_event(self,data:dict) -> List[TaskResult]:

        # 1. 解析命令
        cmd_event = data.get("cmd_event")
        if not cmd_event:
            print("命令为空")
            none_result = []
            none_result.append(CommandExecutor.create_none_result())
            return none_result
        # 2. 解析参数
        params = data.get("params")
        if not params:
            print("参数为空")
            none_result = []
            none_result.append(CommandExecutor.create_none_result())
            return none_result
        # 3. 解析主机
        hosts_key = data.get("hosts_key")
        if not hosts_key:
            print("主机为空")
            none_result = []
            none_result.append(CommandExecutor.create_none_result())
            return none_result
        
        # 解析sudo
        sudo = data.get("sudo")
        sudo_string = ""
        if sudo:
            psw = "789235"
            sudo_string = f"echo {psw} | sudo -S "

        
        # 4. 锚点参数注入
        rejected_task_config = self.anchor_manager.inject(cmd_event, params)
        if not rejected_task_config:
            logger.error(f"锚点参数注入失败: {cmd_event}|{params}")
            none_result = []
            none_result.append(CommandExecutor.create_none_result())
            return none_result
        
        
        # 添加sudo前缀
        for task in rejected_task_config.tasks:
            if sudo:
                task.command = sudo_string + task.command
        print(f"===========rejected_task_config.tasks:================ \n{rejected_task_config.tasks}")

        # 5. 找到key对应的主机配置 
        # 解析"云主机|10.21.162.157:22|本地shell"
        hosts_name = []
        for key in hosts_key:
            hosts_name.append(key.split("|")[0])
        hosts = {}
        for name in hosts_name:
            hosts[name] = self.remote_hosts[name]

        # 6. 执行任务
        results = await self.command_executor.execute_tasks(rejected_task_config,hosts_input=hosts)
        return results
 

    def check_health(self):
        health_check = self.ssh_manager.health_check()
        return health_check
    
    def load_config_list(self):
        config_list = []
        for file_name in os.listdir("./config/shortcut"):
            if file_name.endswith(".json"):
                config_list.append(file_name.replace(".json",""))
        return config_list

    
    async def save_config(self,data:dict):
        # 1. 解析参数
        name = data.get("name")
        hosts = data.get("hosts")
        directories = data.get("directories")
        memo =  data.get('memo')
        
        if not name:
            print("参数name为空")
            return False,"参数configName为空"
        
        # 2. 持久化保存
        file_name = "./config/shortcut/"+ name+".json"
        if not os.path.exists("./config/shortcut"):
            os.makedirs("./config/shortcut")
        # 检查是否存在
        if os.path.exists(file_name):
            print("配置文件已存在")
            return False,"配置文件已存在"

        with open(file_name, 'w', encoding='utf-8') as file:
            json.dump(data, file, indent=4, ensure_ascii=False)
        return True,"保存成功"

    def load_config(self,name:str):
        # 1. 解析参数
        if not name:
            print("参数name为空")
            return False,"参数configName为空",""
        # 2. 加载配置
        file_name = "./config/shortcut/"+ name+".json"
        if not os.path.exists(file_name):
            print("配置文件不存在")
            return False,"配置文件不存在",""
        with open(file_name, 'r', encoding='utf-8') as file:
            config = json.load(file)
        return True,"加载成功",config
    
    def delete_config(self,name:str):
        # 1. 解析参数
        if not name:
            print("参数name为空")
            return False,"参数configName为空"
        # 2. 删除配置
        file_name = "./config/shortcut/"+ name+".json"
        if not os.path.exists(file_name):
            print("配置文件不存在")
            return False,"配置文件不存在"
        os.remove(file_name)
        return True,"删除成功"

    # 初始化一个终端
    async def init_terminal(self,data):
        # 1. 解析参数
        name = data.get("name")
        host = data.get("host")
        port = data.get("port")
        username = data.get("username")
        password = data.get("password")
        if not name or not host or not port or not username or not password:
            print("参数错误")
            return False,"参数错误"


        # 2. 检查是否已存在
        key = f"{name}|{host}:{port}|{username}"
        if not self.ssh_manager.has_connection(key):
            print("主机不存在")
            health_check = self.ssh_manager.health_check()
            print("健康检查:", health_check)
            return False,"主机不存在"
        
        host = Host(name=name,host=host,port=port,username=username,password=password)
        
        try:
            # 获取远程连接
            # self.ssh_manager.get_connection(host)
            # self.login_config.hosts[name] = host
            # self.remote_hosts[name] = host

            load_time = time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime())
            cmd_output_dir = "cmd_output_log/"+"tmp-shell-"+name+"-"+load_time

            # 拷贝一份副本
            task_temp = copy.deepcopy(self.temp_shell_init_task)


            await self.command_executor.ssh_manager_stream.execute_streaming_command(
                host=host,
                task=task_temp,
                cmd_output_dir=cmd_output_dir,
                output_callback=self.temp_shell_output)


            connection_stats = self.ssh_manager.get_connection_stats()
            print("连接信息:", connection_stats)

            health_check = self.ssh_manager.health_check()
            print("健康检查:", health_check)

            return True,"登录成功"
        except Exception as e:
            logger.error(f"登录失败: {key}, 错误: {e}")
            return False,str(e)


    def temp_shell_output(self,host:Host,data:str):
        print(data)

    def download_file(self,data:dict):

        # 1. 解析参数
        # id = data.get("id")
        time = data.get("time")
        event = data.get("event")
        srcIp = data.get("srcIp")
        srcPath = data.get("srcPath")
        srcUsername = data.get("srcUsername")
        srcPassword = data.get("srcPassword")
        destIp = data.get("destIp")
        destPath = data.get("destPath")
        destUsername = data.get("destUsername")
        destPassword = data.get("destPassword")
        id = (event,srcIp,srcUsername,srcPath,destIp,destUsername,destPath,time)


        # 2. 检查参数
        if not srcIp or not srcPath or not srcUsername or not srcPassword or not destIp or not destPath or not destUsername or not destPassword:
            print("参数错误")
            return False,"参数错误"

        

        # 清理已完成的线程
        ids = list(self.scp_thread_map.keys())
        for i in ids:
            if not self.scp_thread_map[i].is_alive():
                del self.scp_tool_map[i]
                del self.scp_thread_map[i]

        # 3. 创建scp连接
        self.scp_tool_map[id] = SCPTool(hostname=srcIp, username=srcUsername, password=srcPassword)
        self.scp_tool_map[id].set_print_to_console(True)

        self.scp_tool_map[id].connect()

        # 4. 下载文件
        self.scp_thread_map[id] = threading.Thread(target=self.download_task,args=(id,srcPath,destPath))


        # monitor_thread = threading.Thread(target=monitor_progress)

        # self.scp_thread_map[id].daemon = True
        self.scp_thread_map[id].start()

        # 等待下载线程完成
        # download_thread.join()

        return True,"下载中"
    
    def download_task(self,id,srcPath,destPath,recursive=False):
        try:
            self.scp_tool_map[id].download(srcPath, destPath,recursive)
        except Exception as e:
            print(f"下载出错: {e}")
        finally:
            # time.sleep(0.5)
            if id in self.scp_tool_map:
                self.scp_tool_map[id].close()
                # del self.scp_tool_map[id]

    def upload_task(self,id,srcPath,destPath,recursive=False):
        try:
            self.scp_tool_map[id].upload(srcPath, destPath,recursive)
        except Exception as e:
            print(f"上传出错: {e}")
        finally:
            # time.sleep(0.5)
            if id in self.scp_tool_map:
                self.scp_tool_map[id].close()
                # del self.scp_tool_map[id]





    def stop_transfer(self,data:dict):
        #  解析参数
        # time = data.get("time")
        # event = data.get("event")
        # srcIp = data.get("srcIp")
        # srcPath = data.get("srcPath")
        # srcUsername = data.get("srcUsername")
        # srcPassword = data.get("srcPassword")
        # destIp = data.get("destIp")
        # destPath = data.get("destPath")
        # destUsername = data.get("destUsername")
        # destPassword = data.get("destPassword")
        # id = (srcIp,srcUsername,srcPath,destIp,destUsername,destPath)

        try:
            ids = list(self.scp_tool_map.keys())

            for id in ids:

                if id in self.scp_tool_map:
                    #  停止传输
                    # self.scp_tool_map[id].interrupt_transfer()
                    self.scp_tool_map[id].close()
                    #  等待线程结束
                    self.scp_thread_map[id].join()

                    # if id in self.scp_tool_map:
                    #     del self.scp_tool_map[id]

                    # if id in self.scp_thread_map:
                    #     del self.scp_thread_map[id]


        except Exception as e:
            print(f"停止传输出错: {e}")
            return False,"停止出错"
        return True,"停止成功"
    
    def get_progress(self,data):
        progress_list = []
        for id in self.scp_tool_map:
            event,method,srcIp,srcUsername,srcPath,destIp,destUsername,destPath,time = id
            progress = self.scp_tool_map[id].get_progress_raw()
            progress["event"] = event
            progress["method"] = method
            progress["srcIp"] = srcIp
            progress["srcUsername"] = srcUsername
            progress["srcPath"] = srcPath
            progress["destIp"] = destIp
            progress["destUsername"] = destUsername
            progress["destPath"] = destPath
            progress_list.append(progress)
        return progress_list


    def start_transfer_scp(self,data:dict):
        #  解析参数
        time = data.get("time")
        event = data.get("event")
        method = data.get("method")
        remoteIP = ""
        remotePort = ""
        remotePath = ""
        remoteUsername = ""
        remotePassword = ""
        localPath = ""


        if not (method=='scp-p2p' or method=='scp-p2s'):
            print("非scp任务")
            return False,"非scp任务"


        if event == "download":
            remoteIP = data.get("sourceIP")
            remotePort = data.get("sourcePort")
            remotePath = data.get("sourcePath")
            remoteUsername = data.get("sourceUsername")
            remotePassword = data.get("sourcePassword")
            localPath = data.get("targetPath")
        elif event == "upload":
            remoteIP = data.get("targetIP")
            remotePort = data.get("targetPort")
            remotePath = data.get("targetPath")
            remoteUsername = data.get("targetUsername")
            remotePassword = data.get("targetPassword")
            localPath = data.get("sourcePath")
        else:
            print("未知scp传输事件")
            return False,"未知scp传输事件"

        if not remoteIP or not remotePort or not remotePath or not remoteUsername or not remotePassword:
            print("参数错误")
            return False,"参数错误"

        id = (event,method,remoteIP,remoteUsername,remotePath,"","",localPath,time)
        # id = (event,srcIp,srcUsername,srcPath,destIp,destUsername,destPath,time)

        # 清理已完成的线程
        ids = list(self.scp_thread_map.keys())
        for i in ids:
            if not self.scp_thread_map[i].is_alive():
                del self.scp_tool_map[i]
                del self.scp_thread_map[i]

        # 3. 创建scp连接
        self.scp_tool_map[id] = SCPTool(hostname=remoteIP, username=remoteUsername, password=remotePassword)
        self.scp_tool_map[id].set_print_to_console(True)

        self.scp_tool_map[id].connect()

        # 传输文件
        if event == "download":
            self.scp_thread_map[id] = threading.Thread(target=self.download_task,args=(id,remotePath,localPath))
        elif event == "upload":
            self.scp_thread_map[id] = threading.Thread(target=self.upload_task,args=(id,localPath,remotePath))

        self.scp_thread_map[id].start()

        return True,"下载中"